package learn.arc;

import com.alibaba.dubbo.remoting.Server;
import com.alibaba.dubbo.remoting.http.HttpBinder;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.EventLoopGroup;
import org.apache.dubbo.cache.filter.CacheFilter;
import org.apache.dubbo.common.Node;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.bytecode.Proxy;
import org.apache.dubbo.common.config.Environment;
import org.apache.dubbo.common.extension.*;
import org.apache.dubbo.common.extension.factory.AdaptiveExtensionFactory;
import org.apache.dubbo.common.extension.factory.SpiExtensionFactory;
import org.apache.dubbo.common.serialize.support.SerializationOptimizer;
import org.apache.dubbo.common.threadpool.ThreadPool;
import org.apache.dubbo.common.threadpool.manager.DefaultExecutorRepository;
import org.apache.dubbo.common.threadpool.manager.ExecutorRepository;
import org.apache.dubbo.common.threadpool.support.cached.CachedThreadPool;
import org.apache.dubbo.common.threadpool.support.eager.EagerThreadPool;
import org.apache.dubbo.common.threadpool.support.fixed.FixedThreadPool;
import org.apache.dubbo.common.threadpool.support.limited.LimitedThreadPool;
import org.apache.dubbo.config.*;
import org.apache.dubbo.config.annotation.DubboService;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
import org.apache.dubbo.config.bootstrap.DubboBootstrapStartStopListener;
import org.apache.dubbo.config.context.ConfigManager;
import org.apache.dubbo.config.invoker.DelegateProviderMetaDataInvoker;
import org.apache.dubbo.config.spring.ServiceBean;
import org.apache.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor;
import org.apache.dubbo.config.spring.beans.factory.annotation.ServiceAnnotationPostProcessor;
import org.apache.dubbo.config.spring.context.DubboBootstrapApplicationListener;
import org.apache.dubbo.config.spring.context.annotation.*;
import org.apache.dubbo.config.spring.extension.SpringExtensionFactory;
import org.apache.dubbo.config.spring.reference.ReferenceBeanBuilder;
import org.apache.dubbo.config.utils.ConfigValidationUtils;
import org.apache.dubbo.container.Container;
import org.apache.dubbo.monitor.Monitor;
import org.apache.dubbo.monitor.support.MonitorFilter;
import org.apache.dubbo.qos.protocol.QosProtocolWrapper;
import org.apache.dubbo.registry.NotifyListener;
import org.apache.dubbo.registry.Registry;
import org.apache.dubbo.registry.RegistryFactory;
import org.apache.dubbo.registry.client.ServiceDiscoveryRegistryDirectory;
import org.apache.dubbo.registry.client.metadata.MetadataUtils;
import org.apache.dubbo.registry.client.migration.MigrationInvoker;
import org.apache.dubbo.registry.client.migration.MigrationRuleHandler;
import org.apache.dubbo.registry.client.migration.MigrationRuleListener;
import org.apache.dubbo.registry.client.migration.ServiceDiscoveryMigrationInvoker;
import org.apache.dubbo.registry.client.migration.model.MigrationRule;
import org.apache.dubbo.registry.client.migration.model.MigrationStep;
import org.apache.dubbo.registry.integration.*;
import org.apache.dubbo.remoting.*;
import org.apache.dubbo.remoting.exchange.ExchangeClient;
import org.apache.dubbo.remoting.exchange.ExchangeHandler;
import org.apache.dubbo.remoting.exchange.Exchanger;
import org.apache.dubbo.remoting.exchange.Exchangers;
import org.apache.dubbo.remoting.exchange.support.ExchangeHandlerAdapter;
import org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler;
import org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeServer;
import org.apache.dubbo.remoting.exchange.support.header.HeaderExchanger;
import org.apache.dubbo.remoting.exchange.support.header.HeartbeatHandler;
import org.apache.dubbo.remoting.transport.AbstractServer;
import org.apache.dubbo.remoting.transport.ChannelHandlerDispatcher;
import org.apache.dubbo.remoting.transport.DecodeHandler;
import org.apache.dubbo.remoting.transport.MultiMessageHandler;
import org.apache.dubbo.remoting.transport.dispatcher.ChannelHandlers;
import org.apache.dubbo.remoting.transport.dispatcher.all.AllDispatcher;
import org.apache.dubbo.remoting.transport.dispatcher.connection.ConnectionOrderedDispatcher;
import org.apache.dubbo.remoting.transport.dispatcher.direct.DirectDispatcher;
import org.apache.dubbo.remoting.transport.dispatcher.execution.ExecutionDispatcher;
import org.apache.dubbo.remoting.transport.dispatcher.message.MessageOnlyDispatcher;
import org.apache.dubbo.remoting.transport.netty.NettyHandler;
import org.apache.dubbo.remoting.transport.netty4.NettyServer;
import org.apache.dubbo.remoting.transport.netty.NettyTransporter;
import org.apache.dubbo.remoting.transport.netty4.NettyServerHandler;
import org.apache.dubbo.rpc.*;
import org.apache.dubbo.rpc.cluster.*;
import org.apache.dubbo.rpc.cluster.directory.StaticDirectory;
import org.apache.dubbo.rpc.cluster.filter.DefaultFilterChainBuilder;
import org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder;
import org.apache.dubbo.rpc.cluster.filter.ProtocolFilterWrapper;
import org.apache.dubbo.rpc.cluster.loadbalance.RandomLoadBalance;
import org.apache.dubbo.rpc.cluster.support.*;
import org.apache.dubbo.rpc.cluster.support.wrapper.AbstractCluster;
import org.apache.dubbo.rpc.cluster.support.wrapper.MockClusterInvoker;
import org.apache.dubbo.rpc.cluster.support.wrapper.MockClusterWrapper;
import org.apache.dubbo.rpc.model.*;
import org.apache.dubbo.rpc.protocol.*;
import org.apache.dubbo.rpc.protocol.dubbo.DubboInvoker;
import org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol;
import org.apache.dubbo.rpc.protocol.grpc.GrpcInvoker;
import org.apache.dubbo.rpc.protocol.grpc.GrpcOptionsUtils;
import org.apache.dubbo.rpc.protocol.grpc.GrpcProtocol;
import org.apache.dubbo.rpc.protocol.injvm.InjvmProtocol;
import org.apache.dubbo.rpc.protocol.rest.RestProtocol;
import org.apache.dubbo.rpc.protocol.rest.RestProtocolServer;
import org.apache.dubbo.rpc.protocol.rest.RestServerFactory;
import org.apache.dubbo.rpc.protocol.tri.TripleInvoker;
import org.apache.dubbo.rpc.proxy.AbstractProxyFactory;
import org.apache.dubbo.rpc.proxy.AbstractProxyInvoker;
import org.apache.dubbo.rpc.proxy.javassist.JavassistProxyFactory;
import org.apache.dubbo.rpc.proxy.wrapper.StubProxyFactoryWrapper;
import org.apache.dubbo.rpc.support.MockInvoker;
import org.apache.dubbo.rpc.support.ProtocolUtils;
import org.apache.dubbo.rpc.support.RpcUtils;
import org.apache.poi.ss.formula.functions.T;
import org.apache.xmlbeans.impl.xb.xmlconfig.Extensionconfig;
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
import org.springframework.context.annotation.ConfigurationClassParser;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;

/**
 * CS结构。基于URL，带参
 *  protocol://username:password@host:port/path?key=value&key=value
 * 核心流程：
 *  服务发布。
 *      服务注册。本地注册、远程注册(服务url写入注册中心)。服务url、注册中心url
 *      服务暴露。服务开启、调用链建立。启动协议容器(nettyServer、tomcat、jetty等)，绑定dispatcher
 *  服务引用。
 *      构建代理。服务接口代理，服务rpc invoker，协议invoker
 *          多注册中心、多服务；注册中心cluster、服务列表cluster
 *          注册协议refer：注册consumer；订阅providers、routers等数据；构建服务列表cluster
 *          遍历注册url，refer；构建StaticDirectory cluster
 *      建立服务url长连接。url、requestHandler
 * provider；线程池、序列化、注册暴露。tomcat，核心dispatcher
 * consumer；序列化、代理引用。http客户端，核心AbstractInvoker
 *
 * 扫描bd、构建config；export/get注册发现；代理(便于统一调用)、装饰器链
 *  发布、注册。
 *  发现、引用。
 *
 * 分配：线程池分配(容器执行)、handler分配(dubbo ChannelHandler链，handlerMapping)
 *
 */
public class Dubbo {

    /**
     * provider、consumer、线程池、通信
     */
    public static class Concept {
        /**
         * 框架设计
         * https://dubbo.apache.org/zh/docsv2.7/dev/design/
         */
        public static void pandect(){
            /* step1，business，业务层。接口、实现*/

            /* step2，RPC，封装、代理*/
            // 1，config；配置层。
            AbstractConfig config;
            {
                ServiceConfig serviceConfig;
                ReferenceConfig referenceConfig;
            }
            // 2，proxy；服务代理层。统一方式调用
            ProxyFactory proxyFactory;
            // 3，registry；注册中心层
            Registry registry;
            RegistryFactory registryFactory;
            RegistryProtocol registryProtocol;// 关联rf，注册服务
            // 4，cluster；路由层。集群路由、负载均衡
            Cluster cluster;
            Directory directory;// 服务列表；通过router筛选服务
            Router router;// 按路由规则选出子集，比如读写分离，应用隔离等
            LoadBalance lb;// 负载均衡
            // 5，monitor；监控层
            Monitor monitor;
            MonitorFilter monitorFilter;
            ProtocolFilterWrapper filterWrapper;// 引入
            // 6，protocal；远程调用层。
            Protocol protocol;
            Invoker invoker;
            Exporter exporter;

            /* step3，Remoting，通信层。*/

        }

        /*
         * dubbo配置
         *  https://dubbo.apache.org/zh/docs/references/configuration/overview/
         *  配置优先级：方法、接口、reference/service、consumer/provider
         *  reference/service为consumer/provider虚拟分组
         *  所有配置最终汇聚到URL，传递给下级模块
         *
         */
        URL dubboUrl;
        RpcContext rpcContext;// 隐式参数

        public static void config(){
            // 配置基类；定义工具方法、模板方法(refresh系列)
            AbstractConfig abstractConfig;

            /* step1，应用级配置*/
            ApplicationConfig applicationConfig;// 应用配置；
            ProtocolConfig protocolConfig;// 协议配置；
            RegistryConfig registryConfig;// 注册中心配置；

            ConfigCenterConfig config;// 配置中心
            MonitorConfig monitorConfig;// 监控配置
            MetricsConfig metricsConfig;// 度量配置

            /* step2，服务级配置*/
            // 配置属性getter、setter
            AbstractMethodConfig methodConfig;
            // 接口维度；组合method config、应用级config
            AbstractInterfaceConfig interfaceConfig;// 重写processExtraRefresh
            AbstractReferenceConfig abstractReferenceConfig;
            AbstractServiceConfig abstractServiceConfig;

            {
                // 消费者、提供者配置。getter、setter
                ConsumerConfig consumerConfig;
                ProviderConfig providerConfig;

                // 组合ConsumerConfig、ProviderConfig。重写preProcessRefresh
                ReferenceConfigBase referenceConfigBase;// 定义get、destroy方法
                ServiceConfigBase serviceConfigBase;// 定义export系列方法
                // 重写postProcessRefresh；实现服务注册发现方法
                ReferenceConfig referenceConfig;
                ServiceConfig serviceConfig;
            }

        }

        /*
         * export导出服务。装配实例，包装增强；本地注册；远程注册；暴露服务(启动server、dispatcher)
         * refer引用服务。代理实例，包装增强；注册服务监听；开启客户端长连接
         * 包装：协议包装、集群包装
         * 协议顺序：包装协议、注册协议、服务协议
         *
         * export时，代理target为服务实现类，包装类前置执行；
         *  注册协议，服务url写入注册中心，调用服务协议
         *  服务协议，创建server，监听、分发请求
         * refer时，代理target为协议实现，包装类后置执行。
         *  注册协议，创建ClusterInvoker，监听服务列表
         *  服务协议，创建客户端Invoker、客户端长连接
         *
         */
        public static void protocal(){

            Protocol protocol;
            {
                // 包装类；装饰器模式，Invoker附加功能
                ProtocolFilterWrapper filterWrapper;// 过滤器
                {
                    FilterChainBuilder filterChainBuilder;
                    Filter filter;
                }
                ProtocolListenerWrapper listenerWrapper;// 监听器；
                {
                    ExporterListener exporterListener;// 响应exported、unexport事件
                }
                QosProtocolWrapper qosProtocolWrapper;// 服务质量监控，Quality Of Service
                ProtocolSerializationWrapper serializationWrapper;// 废弃？

                /*
                 * 注册协议，dubbo spi文件中定义关联
                 *  spi setter注入，默认获取属性名对应的url值
                 *  export、refer中获取服务协议；供protocol使用
                 */
                // 对应service-discovery-registry协议，暴露到本地
                // 先暴露服务(调用通信协议export)，再注册到注册中心。service-discovery-registry
                RegistryProtocol registryProtocol;
                // 对应registry协议，暴露到远程。registry
                InterfaceCompatibleRegistryProtocol interfaceCompatibleRegistryProtocol;

                // 服务协议。启动容器、注册到dispatcher。
                // 项目中通信协议只有一个，注册协议多个
                AbstractProtocol abstractProtocol;
                {
                    // 本地调用的伪协议，不开启端口
                    InjvmProtocol injvmProtocol;
                    DubboProtocol dubboProtocol=null;
                    {
                        ExchangeHandler exchangeHandler=null;// dubbo协议的dispatcher
                        Exchangers.bind((URL)null, exchangeHandler);// 开启服务器
                        Exchangers.connect((URL)null, exchangeHandler);// 开启客户端
                    }

                    AbstractProxyProtocol proxyProtocol;// 代理协议；代理netty？
                    {
                        RestProtocol restProtocol;
                        RestServerFactory restServerFactory;// 按协议类型，创建server
                        HttpBinder httpBinder;// spi机制加载
                        RestProtocolServer restProtocolServer;

                        GrpcProtocol grpcProtocol;
                        AbstractProxyProtocol.ProxyProtocolServer proxyProtocolServer;
                        GrpcProtocol.GrpcRemotingServer grpcRemotingServer;
                        GrpcOptionsUtils grpcOptionsUtils;// 通过NettyServerBuilder构建
                    }
                }
            }
        }

        /**
         *
         */
        public static void netty(){
            io.netty.channel.ChannelHandler nettyChannelHandler;
            Filter filter;
            {
                ProtocolFilterWrapper filterWrapper;// 过滤器
                DefaultFilterChainBuilder filterChainBuilder;// 责任链

            }
            ChannelHandler dubboChannelHandler;

        }

        /*
         * 集群、容错
         * https://dubbo.apache.org/zh/docs/advanced/fault-tolerent-strategy/#available-cluster
         *
         */
        public static void cluster(){
            Cluster cluster;
            {
                MockClusterWrapper mockClusterWrapper;// 包装类

                // 调用目前可用的实例（只调用一个），如果当前没有可用的实例，则抛出异常。通常用于不需要负载均衡的场景
                AvailableCluster availableCluster;
                // 容错策略
                AbstractCluster abstractCluster;
                {
                    FailoverCluster failoverCluster;// 失败自动切换重试，默认
                    FailfastCluster failfastCluster;// 快速失败，只发起一次调用
                }
            }

            Node node;
            Directory directory;
            {
                // 静态目录；注册中心
                StaticDirectory sd;

                // 动态目录；服务列表
                DynamicDirectory dd;// 实现NotifyListener，监听注册中心
                NotifyListener notifyListener;
                RegistryDirectory rd;
                ServiceDiscoveryRegistryDirectory sdrd;

            }

        }

        /*
         * 执行过程
         * refer代理调用，包装元素执行，选择服务、执行客户端逻辑、长连接调用；
         * service server接收请求，server处理器(线程模型选择)，dubbo dispatcher分发，包装元素执行，service代理执行
         *
         * invoker层级：
         *  registryClusterInvoker。注册中心集群invoker
         *  migrationInvoker。注册中心invoker
         *  serviceDiscoveryInvoker。服务发现invoker集群，migrationInvoker持有
         *  DubboInvoker等通信invoker，桥接通信层
         */
        public static void proxy(){
            ProxyFactory proxyFactory;// 构建反射调用的实例，通过Method实例调用
            Exporter exporter;// provider导出，包含Invoker
            Invoker invoker;// 执行器；封装URL、service、interface
            {
                AbstractProxyInvoker abstractProxyInvoker;// provider invoker
                ClusterInvoker clusterInvoker;// consumer引用的集群invoker；处理负载均衡、容错、重试等
                {
                    AbstractClusterInvoker abstractClusterInvoker;
                    MigrationInvoker migrationInvoker;
                    // 负载均衡；从服务列表中获取执行invoker
                    LoadBalance loadBalance;
                    RandomLoadBalance randomLoadBalance;
                }
                AbstractInvoker abstractInvoker;// consumer执行invoker
                {
                    DubboInvoker dubboInvoker;
                    GrpcInvoker grpcInvoker;
                    TripleInvoker tripleInvoker;
                    AbstractProxyProtocol abstractProxyProtocol;// 匿名内部类
                    org.apache.dubbo.rpc.protocol.dubbo.ChannelWrappedInvoker channelWrappedInvoker;
                    org.apache.dubbo.rpc.protocol.injvm.InjvmInvoker injvmInvoker;

                }

                // 包装
                MockInvoker mockInvoker;// 模拟
                InvokerWrapper invokerWrapper;
                InvokerListener invokerListener;// 监听器
                DelegateProviderMetaDataInvoker delegateProviderMetaDataInvoker;// 元数据
            }

        }

        /*
         * 线程模型；https://www.cnblogs.com/xhj123/p/9095278.html
         * provicer，三级；netty boss、worker为IO线程池，dubbo本身为业务线程池
         *  如provider逻辑能迅速完成，并不会发起新的请求，在IO线程上处理会更快，因为减少了线程池调度。
         * consumer，netty等通讯的单级线程池。
         */
        public static void threadPool(){
            Dispatcher dispatcher=null;// dubbo任务线程分发。容器中关联
            ChannelHandler ch = null;
            URL url=null;
            ChannelHandler channelHandler = dispatcher.dispatch(ch, url);
            {
                // 装饰器模式，最终调用Dispatcher.dispatch分配线程，执行请求
                ChannelHandlers.wrap(ch, url);

                AllDispatcher allDispatcher;// 所有消息都派发到业务线程池
                DirectDispatcher directDispatcher;// 所有消息都不派发到业务线程池，全部在IO线程上直接执行
                MessageOnlyDispatcher messageOnlyDispatcher;// 只有请求响应消息派发到业务线程池，其他连接断开事件/心跳等消息，直接在IO线程上执行
                ExecutionDispatcher executionDispatcher;// 只把请求类消息派发到业务线程池处理，但是响应和其它连接断开事件，心跳等消息直接在IO线程上执行
                ConnectionOrderedDispatcher connectionOrderedDispatcher;// 在IO线程上，将连接断开事件放入队列，有序逐个执行，其它消息派发到业务线程池处理

                ThreadPool threadPool;// dubbo业务线程池，适配java Executor；spi，threadpool参数
                FixedThreadPool fixedThreadPool;// 固定
                CachedThreadPool cachedThreadPool;// 弹性，自动伸缩
                LimitedThreadPool limitedThreadPool;//自动增加，不自动收缩
                EagerThreadPool eagerThreadPool;
            }

        }

        // https://dubbo.apache.org/zh/docs/advanced/service-container/
        public static void container(){
            Container container;
            Server server;

        }

    }

    /**
     *
     */
    public static void exportDemo(){
//        new EmbeddedZooKeeper(2181, false).start();
        // 服务实现
        Dubbo demoService = new Dubbo();
        // 当前应用配置
        ApplicationConfig application = new ApplicationConfig();
        application.setName("demo-provider");
        // 连接注册中心配置
        RegistryConfig registry = new RegistryConfig();
        registry.setAddress("zookeeper://127.0.0.1:2181");
        // 服务提供者协议配置
        ProtocolConfig protocol = new ProtocolConfig();
        protocol.setName("dubbo");
        protocol.setPort(12345);
        protocol.setThreads(200);
        // 注意：ServiceConfig为重对象，内部封装了与注册中心的连接，以及开启服务端口
        // 服务提供者暴露服务配置
        ServiceConfig<Dubbo> service = new ServiceConfig<>();
        // 此实例很重，封装了与注册中心的连接，请自行缓存，否则可能造成内存和连接泄漏
        service.setApplication(application);
        service.setRegistry(registry); // 多个注册中心可以用setRegistries()
        service.setProtocol(protocol); // 多个协议可以用setProtocols()
        service.setInterface(Dubbo.class);
        service.setRef(demoService);
        service.setVersion("1.0.0");
        // 暴露及注册服务
        service.export();
    }

    /**
     *
     */
    public static void refDemo(){
        ApplicationConfig applicationConfig = new ApplicationConfig();
        applicationConfig.setName("dubbo_consumer");
        RegistryConfig registryConfig = new RegistryConfig();
        registryConfig.setAddress("zookeeper://127.0.0.1:2181");
        ReferenceConfig<Protocol> referenceConfig = new ReferenceConfig<>();
        referenceConfig.setApplication(applicationConfig);
        referenceConfig.setRegistry(registryConfig);
        referenceConfig.setInterface(Protocol.class);
        Protocol userService = referenceConfig.get();
    }
    /**
     * 注册暴露服务
     *  注册。本地注册(本地引用)、注册中心注册
     *  发布。启动netty server，监听端口。
     *
     * 服务实例；遍历请求协议，构建请求url，注册到本地，开启netty，注册到注册中心；
     * 协议顺序：包装协议、registry、dubbo
     *
     * exportLocal；injvm协议暴露
     * service-discovery-registry；注册到本地
     * doLocalExport；构建代理invoker，触发服务协议暴露
     */
    public static void export(){
        DubboService service;

        ServiceConfig serviceConfig = new ServiceConfig();
        List<Exporter<?>> exporters;// 全局exporter，包括本地、远程；用于unexport
        serviceConfig.export();
        {
            // 1，初始化DubboBootstrap、元数据ServiceMetadata
            serviceConfig.init();

            // 2，dubbo config属性刷新
            serviceConfig.refresh();
            {
                // 1
                serviceConfig.preProcessRefresh();

                // 2，refresh逻辑，配置属性刷新

                // 3，
                serviceConfig.processExtraRefresh(null, null);

                // 4，
                serviceConfig.postProcessRefresh();
            }

            // 3，暴露服务
            serviceConfig.doExport();
            {
                // 1，获取注册中心url列表、通信协议配置列表；遍历通信协议列表，发布服务(暴露、注册)
                serviceConfig.doExportUrls();
                {
                    // 1，构建、保存provider模型
                    applicationModel();

                    // 2，获取到注册中心的url
                    List<URL> registryURLs = ConfigValidationUtils.loadRegistries(serviceConfig, true);
                    ProtocolConfig protocolConfig=null;

                    // 3，遍历服务协议：
                    //  获取访问url；
                    //  暴露到本地仓库；
                    //  注册到远程仓库。构建invoker时，协议替换为注册协议。
                    serviceConfig.doExportUrlsFor1Protocol(protocolConfig, registryURLs);
                    {
                        // 1，构建服务请求url
                        URL url = serviceConfig.buildUrl(protocolConfig, registryURLs, null);

                        // 2，处理url；注册、发布
                        // 根据scope进行对应暴露；默认暴露到本地(injvm协议)、远程
                        // exportRemote中，invoker协议扭转为注册协议，服务url存至export参数
                        serviceConfig.exportUrl(url, registryURLs);
                        {
                            // 构建代理、暴露服务。
                            // 有注册中心时，协议扭转为注册协议。注册协议export时，调用通信协议export
                            serviceConfig.doExportUrl(url, false);
                                ProxyFactory PROXY_FACTORY = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
                                Invoker<?> invoker = PROXY_FACTORY.getInvoker(null, Dubbo.class, url);
                                protocolExport();
                        }
                    }


                }

                // 2，命名映射？触发ServiceListener
                serviceConfig.exported();

            }

            // 4，dubbo启动，处理纯dubbo逻辑
            DubboBootstrap dubboBootstrap = DubboBootstrap.getInstance();
            dubboBootstrap.start();// 已初始化
            dubboBootstrap.doStart();
            {
                // 1，处理异步暴露、未暴露服务
                dubboBootstrap.exportServices();

                // 2，导出元数据、注册本地服务实例
                dubboBootstrap.exportMetadataService();
                dubboBootstrap.registerServiceInstance();

                // 3，处理服务引用
                dubboBootstrap.referServices();

                // 4，触发DubboBootstrapStartStopListener，spi加载
                DubboBootstrapStartStopListener dubboBootstrapStartStopListener;
            }
        }
    }

    /**
     *
     */
    public static void applicationModel(){
        // dubbo应用，存储元数据
        ApplicationModel applicationModel;
        {
            Environment environment;// 环境配置；包括：os、jvm、-D参数、dubbo.properties等
            ConfigManager configManager;// 配置中心
            ServiceRepository serviceRepository;// 服务仓库
            {
                ServiceDescriptor serviceDescriptor;// 服务接口描述，方法名-方法
                ServiceMetadata serviceMetadata;// 元数据；版本、分组、附加信息(attachments、attributeMap)等
                // provider模型，包含serviceKey，instance，config，registerUrls，serviceDescriptor，serviceMetadata
                ProviderModel providerModel;
                // consumer模型，包含serviceKey，proxy，config，registerUrls，serviceDescriptor，serviceMetadata
                ConsumerModel consumerModel;
            }
        }


    }

    /**
     *
     */
    public static void protocolExport() throws Exception{


        // 协议，dubbo spi文件中定义关联
        // 对应service-discovery-registry协议，暴露到本地
        RegistryProtocol registryProtocol=null;
        registryProtocol.export(null);
        {
            // 1，获取远程注册url、本地注册url

            // 2，本地注册。构建代理invoker，触发服务协议暴露
            registryProtocol.doLocalExport(null, null);

            // 3，服务url发布到注册中心
            registryProtocol.register(null, null);

        }
        // 对应registry协议，暴露到远程。RegistryProtocol子类，暴露代码同
        InterfaceCompatibleRegistryProtocol interfaceCompatibleRegistryProtocol;

        // 服务协议
        DubboProtocol dubboProtocol=null;// 发布服务，开启netty
        dubboProtocol.export(null);
        {
            // 1，构建exporter；放入协议exporterMap。

            // 2，打印日志

            // 3，无时创建netty4 server，有时reset
            dubboProtocol.openServer(null);
            protocolServer();

            // 4，序列化优化，暂无实现。
            dubboProtocol.optimizeSerialization(null);
            SerializationOptimizer serializationOptimizer;

        }

    }

    /**
     *
     */
    public static void protocolServer() throws Exception{
        DubboProtocol dubboProtocol=null;
        URL dubboUrl = null;
        ExchangeHandler dubboRequestHandler = null;

        dubboProtocol.openServer(dubboUrl);
        {
            dubboProtocol.createServer(dubboUrl);
            Exchangers.bind(dubboUrl, dubboRequestHandler);// 创建server
            new HeaderExchanger().bind(dubboUrl, dubboRequestHandler);
            {
                ChannelHandler decodeAndRequestHandler = new DecodeHandler(new HeaderExchangeHandler(dubboRequestHandler));
                RemotingServer remotingServer = Transporters.bind(dubboUrl, decodeAndRequestHandler);
                {
                    remotingServer = new NettyTransporter().bind(dubboUrl, decodeAndRequestHandler);
                    NettyServer dubboNettyServer = new NettyServer(dubboUrl, decodeAndRequestHandler);
                    ChannelHandler wrapDecodeAndRequestHandler = ChannelHandlers.wrap(decodeAndRequestHandler, dubboUrl);
                    AbstractServer abstractServer = new AbstractServer(dubboUrl, wrapDecodeAndRequestHandler);
                    {
                        // 1，获取ip、port

                        // 2，开启server；调用子类方法
                        dubboNettyServer.doOpen();
                        ServerBootstrap serverBootstrap;

                        // 3，创建业务线程池
                        ExecutorRepository executorRepository = ExtensionLoader.getExtensionLoader(ExecutorRepository.class).getDefaultExtension();
                        ExecutorService executor = ((DefaultExecutorRepository)executorRepository).createExecutorIfAbsent(dubboUrl);
                        ExtensionLoader.getExtensionLoader(ThreadPool.class).getAdaptiveExtension().getExecutor(dubboUrl);
                    }
                }
                HeaderExchangeServer server = new HeaderExchangeServer(remotingServer);// 返回适配类
            }
        }

        // 适配器模式
        ChannelHandler dubboChannelHandler;
        NettyServerHandler nettyServerHandler;
        RemotingServer remotingServer;
        NettyServer dubboNettyServer;
    }
    /**
     * 服务引用，创建服务代理。注册、开启客户端
     *  注册到注册中心；监听服务列表变化，刷新
     *  代理实例
     * 协议包装；集群包装。
     *
     * 根据服务key，获取服务请求url列表；选择url及对应长连接，请求
     */
    public static void refer(){
        ReferenceConfig referenceConfig = new ReferenceConfig();
        URL dubboRegistryUrl=null;
        Class referClazz=null;
        Map<String, String> urlParamMap=null;

        referenceConfig.get();// 获取代理
        referenceConfig.init();
        referenceConfig.createProxy(urlParamMap);// 协议refer、创建代理。引用分两类，injvm、其他
        {
            // 1，注册协议；构建ClusterInvoker
            InterfaceCompatibleRegistryProtocol remoteRegistryProtocol=null;
            RegistryProtocol registryProtocol=null;
            InjvmProtocol injvmProtocol;// 返回包装对象

            Invoker<Object> refer = remoteRegistryProtocol.refer(referClazz, dubboRegistryUrl);
            {
                Registry registry=null;// spi
                Cluster cluster=null;// url参数获取集群模式。ExtensionLoader中装配注入，adaptive。集群包装
                URL consumerUrl=null;// urlParamMap构建
                // 获取集群包装的invoker
                Invoker<Object> refObj = remoteRegistryProtocol.doRefer(cluster, registry, referClazz, dubboRegistryUrl, urlParamMap);
                {
                    // 1，构建集群invoker。
                    ClusterInvoker migrationInvoker = remoteRegistryProtocol.getMigrationInvoker(registryProtocol, cluster, registry, referClazz, dubboRegistryUrl, consumerUrl);
                    // registry协议实际返回实例；invoker、serviceDiscoveryInvoker 属性为null
                    // service-discovery-registry协议，对应RegistryProtocol
                    // serviceDiscoveryInvoker属性，doCreateInvoker中创建
                    MigrationInvoker migrationInvoker1;

                    // 2，按协议触发RegistryProtocolListener，re-refer。spi只有 MigrationRuleListener
                    Invoker interceptInvoker = remoteRegistryProtocol.interceptInvoker(migrationInvoker, dubboRegistryUrl, consumerUrl, dubboRegistryUrl);
                    RegistryProtocolListener registryProtocolListener=null;
                    MigrationRuleListener listener;
                    reRefer(remoteRegistryProtocol, (MigrationInvoker) migrationInvoker, dubboRegistryUrl, consumerUrl);

                }
            }
            // 注册中心invoker集群
            Invoker clusterInvoker = Cluster.getCluster("").join(new StaticDirectory(Collections.emptyList()));
            {
                // 持有invokers
                StaticDirectory sd = new StaticDirectory(null, null, null);

                //
                FailoverCluster cluster1 = new FailoverCluster();
                cluster1.join(sd);
                cluster1.doJoin(sd);
                clusterInvoker = new FailoverClusterInvoker(sd);
            }

            // 2，
            MetadataUtils.publishServiceDefinition(null);

            // 3，构建代理
            ProxyFactory PROXY_FACTORY = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();

            // 注册中心通知，建立长连接、构建AbstractInvoker
            registerNotify();
        }
    }

    private static void reRefer(InterfaceCompatibleRegistryProtocol remoteRegistryProtocol, MigrationInvoker migrationInvoker, URL dubboRegistryURL, URL consumerUrl) {
        // 触发重新refer
        RegistryProtocolListener registryProtocolListener=null;
        MigrationRuleListener migrationRuleListener=null;// 唯一监听器
        migrationRuleListener.onRefer(remoteRegistryProtocol, migrationInvoker, consumerUrl, dubboRegistryURL);
        // 处理配置、URL，刷新invoker
        MigrationRuleHandler migrationRuleHandler=null;// migrationInvoker、consumerUrl构建
        MigrationRule rule=MigrationRule.INIT;// 构造器中初始化，默认INIT
        migrationRuleHandler.doMigrate(rule);// invoker为MigrationInvoker
        MigrationStep step=MigrationStep.APPLICATION_FIRST;// 从url中获取step，默认APPLICATION_FIRST
        migrationRuleHandler.refreshInvoker(step, 1.0f,rule);
        // 跳转到首个invoker MigrationInvoker
        migrationInvoker.migrateToApplicationFirstInvoker(rule);
        {
            // 1，刷新invoker；设置serviceDiscoveryInvoker，为DubboInvoker等的集合
            migrationInvoker.refreshServiceDiscoveryInvoker(null);
            {
                // 1，获取serviceDiscoveryInvoker。现值为null
                ClusterInvoker<T> serviceDiscoveryInvoker = remoteRegistryProtocol.getServiceDiscoveryInvoker(null, null, null, null);
                {
                    // 服务列表
                    ServiceDiscoveryRegistryDirectory<T> sdrDirectory = new ServiceDiscoveryRegistryDirectory<>(null, null);

                    Registry registry=null;// spi
                    Cluster cluster=null;// spi，RegistryProtocol.refer中创建；
                    serviceDiscoveryInvoker = remoteRegistryProtocol.doCreateInvoker(sdrDirectory, cluster, registry, null);
                    {
                        // 1，注册到consumer节点
                        registry.register(null);
                        // 2，创建路由链
                        sdrDirectory.buildRouterChain(null);
                        // 3，订阅监听providers、configurators、routers等数据
                        sdrDirectory.subscribe(null);
                        // 4，关联invoker、服务列表
                        serviceDiscoveryInvoker = (ClusterInvoker<T>) cluster.join(sdrDirectory);
                    }
                    // 触发通信协议refer
                    sdrDirectory.toInvokers();
                    sdrDirectory.notify(null);// 触发
                    NotifyListener notifyListener;
                }

            }

        }

        // invoke时，获取invoker执行
        Invocation invocation=null;
        migrationInvoker.invoke(invocation);
        ClusterInvoker<T> serviceDiscoveryInvoker =null;// 调用到此类
        ((AbstractClusterInvoker)serviceDiscoveryInvoker).invoke(invocation);
        // 获取服务列表
        List<Invoker> list = ((AbstractClusterInvoker) serviceDiscoveryInvoker).list(invocation);
        AbstractInvoker abstractInvoker=null;// 服务为AbstractInvoker子类
        abstractInvoker.invoke(invocation);
    }

    /**
     *
     */
    public static void registerNotify(){
        DynamicDirectory dynamicDirectory=null;

        // 1，注册中心下发服务列表，触发调用
        dynamicDirectory.notify(null);
        ((RegistryDirectory)dynamicDirectory).refreshOverrideAndInvoker(null);
        ((RegistryDirectory)dynamicDirectory).refreshInvoker(null);
        ((RegistryDirectory)dynamicDirectory).toInvokers(null);

        // 2，调用服务协议的refer，建立长连接，构建DubboInvoker
        DubboProtocol dubboProtocol=null;
        URL serviceUrl=null;
        Class referClazz=null;

        dubboProtocol.refer(referClazz, serviceUrl);
        dubboProtocol.protocolBindingRefer(referClazz, serviceUrl);
        {
            ExchangeClient[] clients = dubboProtocol.getClients(serviceUrl);
            Exchangers.connect(serviceUrl, (ExchangeHandler)null);// 建立连接
            Set<Invoker<?>> invokers = null;// 协议invoker set
            DubboInvoker dubboInvoker = new DubboInvoker(referClazz, serviceUrl, clients,invokers);

        }
    }

    /**
     * https://dubbo.apache.org/zh/docsv2.7/dev/source/service-invoking-process/
     * 服务请求：
     *  consumer通过proxy对象发起调用，编码、序列化请求
     *  client发送请求到server
     *  server接收请求、解码后，由dispatcher分配线程池
     *  requestHandler确定执行handler，执行逻辑
     *
     * traceId；全局跟踪id。可通过filter，设置RpcContext实现。
     *
     * 数据传递
     *  req/resp，传递请求参数、返回信息
     *  RpcContext；通过ThreadLocal方式，传递通用信息
     *
     *
     */
    public static void invoke(){
        StaticDirectory registerSd = null;
        Invocation invocation = null;
        FailoverClusterInvoker clusterInvoker = new FailoverClusterInvoker(registerSd);
        clusterInvoker.invoke(null);
        {
            // 路由过滤。调用sd的路由，读写分离，应用隔离等过滤。
            List<Invoker> list = clusterInvoker.list(invocation);
            {
                clusterInvoker.getDirectory().list(invocation);
                registerSd.doList(invocation);
            }

            // 按url参数选择负载均衡策略
            LoadBalance lb = clusterInvoker.initLoadBalance(list, invocation);

            // 执行；注册中心invoker实际为 MigrationInvoker
            clusterInvoker.doInvoke(invocation, list, lb);
            {
                MigrationInvoker mgInvoker = (MigrationInvoker)clusterInvoker.select();
                clusterInvoker.invokeWithContext(mgInvoker, invocation);
                mgInvoker.invoke(invocation);
                FailoverClusterInvoker serviceClusterInvokers = null;
                serviceClusterInvokers.invoke(invocation);
                DubboInvoker ink = null;
                // 包含service信息、attachement(发送到service)、attributes(不发送到service)
                RpcInvocation rpcInvocation = (RpcInvocation)invocation;
                RpcUtils.attachInvocationIdIfAsync(null, rpcInvocation);
                RpcContext rpcContext;
                // 关联attach；返回的 AsyncRpcResult，同步时调用get阻塞，异步时caller调用get
                Result result = ink.invoke(invocation);
                ink.doInvoke(invocation);
                ExchangeClient client=null;
                client.send(invocation, false);// 无返回
                CompletableFuture<Object> resp = client.request(invocation, null);
            }
        }

        // 装饰器
        MockClusterWrapper mockClusterWrapper;
        MockClusterInvoker mockClusterInvoker;

        // 通信
        ExchangeClient exchangeClient=null;
        {
            // 引用计数
            org.apache.dubbo.rpc.protocol.dubbo.ReferenceCountExchangeClient exchangeClient1=null;

        }

    }

    /**
     * spi：https://www.cnblogs.com/liferecord/p/13445631.html
     *
     */
    public static void spi(){
        // 标记dubbo扩展接口；值为默认扩展点
        SPI spi;
        // 自适应注解。
        //  标记实现类，则类为AdaptiveExtension扩展
        //  标记接口方法，生成代理实现类；按url参数选择实现类
        //      默认属性名：类名转小写，点号分隔，GrpcProtocol--grpc.protocol
        //      类默认值，去除接口名，转小写
        //  无匹配类时，用SPI default。
        Adaptive adaptive;
        {
            Protocol protocol;
            GrpcProtocol grpcProtocol;
        }
        // 条件化激活，标记实现类、方法
        Activate activate;
        {
            Filter filter;
            CacheFilter cacheFilter;
        }

        /*
         * dubbo spi加载器
         *  查找类路径下 META-INF/dubbo, META-INF/dubbo/internal,META-INF/services目录下，扩展点接口名相同的文件
         *  当一个具体的扩展点的实现有其setter方法，且没有被@DisableInject标注、注入类型不是原始类型(long,int,short,String,BigDecimal等)时，该setter方法会被调用，注入ExtensionFactory工厂获取的实例
         */
        ExtensionLoader extensionLoader=ExtensionLoader.getExtensionLoader(Protocol.class);
        {
            // 无包装实现类，返回原类；有包装类，返回层级装饰后的类。
            Object extensionOrWrapper = extensionLoader.getExtension("dubbo");
            // 获取@SPI标记的默认实现
            Object defaultExtension = extensionLoader.getDefaultExtension();// 默认
            // 获取自适应类；自适应类在执行中，通过url参数定位到具体实现类。命令模式？
            Object adaptiveExtension = extensionLoader.getAdaptiveExtension();// 自适应的代理实例
            // 按url参数，获取激活的类
            List activateExtension = extensionLoader.getActivateExtension((URL) null, (String[]) null);// 激活

            // dubbo ioc工厂，ExtensionLoader构造器中调用；为adaptive实例
            // 通过setter方法注入，默认获取属性名对应的url值
            ExtensionFactory extensionFactory;
            {
                AdaptiveExtensionFactory adaptiveExtensionFactory;
                SpiExtensionFactory spiExtensionFactory;
                SpringExtensionFactory springExtensionFactory;
            }
        }
        // java spi；遍历获取实现类
        ServiceLoader serviceLoader=ServiceLoader.load(null);

    }

    /**
     *
     */
    public static void proxy(){
        // spi adaptive加载；构建反射调用的实例，通过Method实例调用
        ProxyFactory proxyFactory;

        // 阿里字节码
        Proxy proxy;
        // Proxy中断点使用，ClassGenerator；getProxy方法
        //如果接口是public修饰的 就在debug的时候使用这个能在E盘下生成class文件，e:/com/alibaba/dubbo/common/bytecode/proxy0/proxy0.class
        //ccm.getClassPool().get("com.alibaba.dubbo.common.bytecode.proxy0").debugWriteFile("e:\\")
        //如果接口没有被public修饰 debug的时候可以用以下方式获取class文件
        //ccp.getClassPool().get("per.qiao.util.proxy0").debugWriteFile("e:\\")

        AbstractProxyInvoker abstractProxyInvoker;// provider invoker

        ClusterInvoker clusterInvoker;// consumer引用的集群invoker
        AbstractClusterInvoker abstractClusterInvoker;
    }


    /**
     *
     */
    public static void spring(){
        EnableDubbo enableDubbo;
        {
            // 1，导入dubbo配置，属性--configBean
            EnableDubboConfig enableDubboConfig;
            DubboConfigConfigurationRegistrar configConfigurationRegistrar;
            DubboConfigConfiguration dubboConfigConfiguration;

            // 2，dubbo bd扫描配置；默认标记类class所在包。引入@Service、@Reference扫描
            DubboComponentScan dubboComponentScan;
            // 注册ServiceAnnotationBeanPostProcessor、ReferenceAnnotationBeanPostProcessor
            DubboComponentScanRegistrar dubboComponentScanRegistrar;
            // ImportBeanDefinitionRegistrar；@Configuration注册bd后执行
            ImportBeanDefinitionRegistrar importBeanDefinitionRegistrar;
            ConfigurationClassParser parser;

            // 实现BeanDefinitionRegistryPostProcessor，bf扫描完成后注册service bd；
            // BeanFactoryPostProcessor中，@Service bean注册为ServiceBean
            ServiceAnnotationPostProcessor serviceAnnotationPostProcessor;

            // 实现InstantiationAwareBeanPostProcessor，处理dubbo @Reference注解注入
            // 实现MergedBeanDefinitionPostProcessor，扫描@Reference属性为待注入
            // AbstractAutowireCapableBeanFactory.populateBean中，postProcessPropertyValues调用，触发InjectionMetadata.inject属性注入
            ReferenceAnnotationBeanPostProcessor referenceAnnotationBeanPostProcessor;
            MergedBeanDefinitionPostProcessor mergedBeanDefinitionPostProcessor;
            ReferenceAnnotationBeanPostProcessor.ReferenceFieldElement referenceFieldElement;// 注入时构建代理实例，spring管理
            ReferenceBeanBuilder beanBuilder;
        }

        ServiceConfig serviceConfig;
        ReferenceConfig referenceConfig;
    }


}
